#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# ---------------------------------------------------------------------------------------------------
#使用模块 Import Module
'''
在Python中，一个.py文件就称之为一个模块（Module）。
1.提高了代码的可维护性
2.编写代码不必从零开始
3.可以避免函数名和变量名冲突

查看Python的所有内置函数: https://docs.python.org/3/library/functions.html

如果不同的人编写的模块名相同怎么办？
为了避免模块名冲突，Python又引入了按目录来组织模块的方法，称为包（Package）。

举个例子，一个abc.py的文件就是一个名字叫abc的模块，一个xyz.py的文件就是一个名字叫xyz的模块。
假设我们的abc和xyz这两个模块名字与其他模块冲突了，于是我们可以通过包来组织模块，避免冲突。
方法是选择一个顶层包名，比如mycompany，按照如下目录存放：
mycompany
    __init__.py
    abc.py
    xyz.py
引入了包以后，只要顶层的包名不与别人冲突，那所有模块都不会与别人冲突。
现在，abc.py模块的名字就变成了mycompany.abc，类似的，xyz.py的模块名变成了mycompany.xyz

请注意，每一个包目录下面都会有一个__init__.py的文件，这个文件是必须存在的，
否则，Python就把这个目录当成普通目录，而不是一个包。__init__.py可以是空文件，
也可以有Python代码，因为__init__.py本身就是一个模块，而它的模块名就是mycompany。

类似的，可以有多级目录，组成多级层次的包结构。比如如下的目录结构：
mycompany
    web
        __init__.py
        www.py
        untils.py
    __init__.py
    abc.py
    xyz.py
文件www.py的模块名就是mycompany.web.www，两个文件utils.py的模块名分别是mycompany.utils和mycompany.web.utils。

自己创建模块时要注意命名，不能和Python自带的模块名称冲突。
例如，系统自带了sys模块，自己的模块就不可命名为sys.py，否则将无法导入系统自带的sys模块。

Python本身就内置了很多非常有用的模块，只要安装完毕，这些模块就可以立刻使用。
以内建的sys模块为例，编写一个TestModule的模块：打开TestModule.py查看

用命令行TestModule.py查看效果:
TestModule.py           => Hello, world!
TestModule.py chry      => Hello, chry!

Python交互环境运行:
>>> import TestModule
>>> TestModule.test()
    Hello, world!

交互环境下不知如何带argv参数    
'''
import TestModule
TestModule.test()

import Hello
sss = Hello()
# ---------------------------------------------------------------------------------------------------
#作用域 action scope
"""
在一个模块中，我们可能会定义很多函数和变量，
但有的函数和变量我们希望给别人使用，有
的函数和变量我们希望仅仅在模块内部使用。

在Python中，是通过_(下划线)前缀来实现的。
正常的函数和变量名是公开的（public），可以被直接引用，比如：abc，x123，PI等；

类似__xxx__这样的变量是特殊变量，可以被直接引用，但是有特殊用途，
比如TestModule.py里面的__author__，__name__就是特殊变量，
TestModule模块定义的文档注释也可以用特殊变量__doc__访问，我们自己的变量一般不要用这种变量名；

类似_xxx和__xxx这样的函数或变量就是非公开的（private），不应该被直接引用，比如_abc，__abc等；

之所以我们说，private函数和变量“不应该”被直接引用，而不是“不能”被直接引用，
是因为Python并没有一种方法可以完全限制访问private函数或变量，
但是，从编程习惯上不应该引用private函数或变量。

private函数或变量不应该被别人引用，那它们有什么用呢？请看例子：
"""
def _private_1(name):
    return 'Hello, %s' % name

def _private_2(name):
    return 'Hi, %s' % name

def greeting(name):
    if len(name) > 3:
        return _private_1(name)
    else:
        return _private_2(name)

print(greeting('yun'))
print(greeting('chry'))
"""
我们在模块里公开greeting()函数，而把内部逻辑用private函数隐藏起来了，
这样，调用greeting()函数不用关心内部的private函数细节，这也是一种非常有用的代码封装和抽象的方法，即：

外部不需要引用的函数全部定义成private，只有外部需要引用的函数才定义为public。
"""








